﻿//AcademicPlanner - course registration planning web app.
//Copyright (C) 2009  Boubacar Diallo

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AcademicPlanner.Presentation.Views.Shared;
using AcademicPlanner.Framework.Helpers;
using AcademicPlanner.Framework.Libraries.Mvc;
using AcademicPlanner.Domain.Models;

namespace AcademicPlanner.Presentation.Controllers
{
	/// <summary>
	/// ControlsController is the Mvc controller for requests
	/// under /Controls/* in the AcademicPlanner application
	/// web site.
	/// </summary>
	/// <remarks>
	/// This controller is responsible for serving user
	/// controls via ajax.
	/// </remarks>
	/// <since>1.0</since>
	[HandleError]
	public class ControlsController : Controller
	{
		/// <summary>
		/// Serves a <c>AcademicPlanForm</c> control.
		/// </summary>
		/// <param name="pScenario">The scenario to use the <c>AcademicPlanForm</c> under.</param>
		/// <param name="pAcademicPlanId">The identifier of the <c>AcademicPlan</c> to use in the form.</param>
		/// <param name="pIncludeCancelButton">Whether or not to include a cancel button in the form.</param>
		/// <returns>The <c>AcademicPlanForm</c> control.</returns>
		/// <exception cref="T:System.Web.HttpException">
		/// Thrown with status code 404 if an academic plan with the given identifier does not exist
		/// in the system.
		/// </exception>
		/// <seealso cref="P:Application"/>
		/// <seealso cref="P:AcademicPlanner.Presentation.AcademicPlannerWebApp.DomainMaster"/>
		/// <seealso cref="P:AcademicPlanner.Domain.DomainMaster.Planning"/>
		/// <seealso cref="M:AcademicPlanner.Domain.Components.AcademicPlanningMngr.GetAcademicPlan(int)"/>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Get)]
		[AjaxOnly]
		[RequireAuthentication]
		public PartialViewResult AcademicPlanForm(AcademicPlanFormScenario pScenario, int pAcademicPlanId, bool? pIncludeCancelButton)
		{
			var vFormModel = new AcademicPlanFormModel();
			var vPlan = Application.DomainMaster.Planning.GetAcademicPlan(pAcademicPlanId);

			if (vPlan == null)
				throw new HttpException(404, Tr("Oops! We could not find the resource you requested."));

			// TODO: QUERY DOMAIN TO SEE IF USER CAN UPDATE ACADEMICPLAN

			vFormModel.AcademicPlan = vPlan;
			vFormModel.Scenario = pScenario;
			vFormModel.IncludeCancelButton = pIncludeCancelButton ?? true;

			return PartialView("AcademicPlanForm", vFormModel);
		}

		/// <summary>
		/// Serves a <c>ProgramForm</c> control.
		/// </summary>
		/// <param name="pScenario">The scenario to use the <c>ProgramForm</c> under.</param>
		/// <param name="pProgramId">The identifier of the <c>Program</c> to use in the form.</param>
		/// <param name="pPlanId">The identifier of the <c>AcademicPlan</c> to use in the form.</param>
		/// <returns>The <c>ProgramForm</c> control.</returns>
		/// <exception cref="T:System.Web.HttpException">
		/// Thrown with status code 404 if an academic program with the given identifier does not exist
		/// in the system.
		/// </exception>
		/// <seealso cref="P:Application"/>
		/// <seealso cref="P:AcademicPlanner.Presentation.AcademicPlannerWebApp.DomainMaster"/>
		/// <seealso cref="P:AcademicPlanner.Domain.DomainMaster.Planning"/>
		/// <seealso cref="M:AcademicPlanner.Domain.Components.AcademicPlanningMngr.GetProgram"/>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Get)]
		[AjaxOnly]
		[RequireAuthentication]
		public PartialViewResult ProgramForm(ProgramFormScenario pScenario, int pProgramId, int pPlanId)
		{
			var vFormModel = new ProgramFormModel();

			vFormModel.PlanId = pPlanId;
			vFormModel.Scenario = pScenario;
			if (pProgramId == 0)
			{
				var vPlan = Application.DomainMaster.Planning.GetAcademicPlan(pPlanId);

				if (vPlan == null)
					throw new HttpException(404, Tr("Oops! We could not find the resource you requested."));
				// TODO: QUERY DOMAIN TO SEE IF USER CAN CREATE PROGRAM UNDER ACADEMICPLAN

				vFormModel.PlanCourses = vPlan.Courses.ToList();
			}
			else
			{
				var vProgram = Application.DomainMaster.Planning.GetProgram(pProgramId);
				if (vProgram == null)
					throw new HttpException(404, Tr("Oops! We could not find the resource you requested."));
				// TODO: QUERY DOMAIN TO SEE IF USER CAN UPDATE PROGRAM

				vFormModel.Program = vProgram;
				vFormModel.PlanCourses = vProgram.Plan.Courses.ToList();
			}

			return PartialView("ProgramForm", vFormModel);
		}

		/// <summary>
		/// Serves a <c>CourseForm</c> control.
		/// </summary>
		/// <param name="pScenario">The scenario to use the <c>CourseForm</c> under.</param>
		/// <param name="pCourseId">The identifier of the <c>Course</c> to use in the form.</param>
		/// <param name="pPlanId">The identifier of the <c>AcademicPlan</c> to use in the form.</param>
		/// <returns>The <c>CourseForm</c> control.</returns>
		/// <exception cref="T:System.Web.HttpException">
		/// Thrown with status code 404 if an academic course or the academic plan with the given 
		/// identifier does not exist in the system.
		/// </exception>
		/// <seealso cref="P:Application"/>
		/// <seealso cref="P:AcademicPlanner.Presentation.AcademicPlannerWebApp.DomainMaster"/>
		/// <seealso cref="P:AcademicPlanner.Domain.DomainMaster.Planning"/>
		/// <seealso cref="M:AcademicPlanner.Domain.Components.AcademicPlanningMngr.GetAcademicPlan(int)"/>
		/// <seealso cref="M:AcademicPlanner.Domain.Components.AcademicPlanningMngr.GetCourse"/>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Get)]
		[AjaxOnly]
		[RequireAuthentication]
		public PartialViewResult CourseForm(CourseFormScenario pScenario, int pCourseId, int pPlanId)
		{
			var vFormModel = new CourseFormModel();

			vFormModel.Scenario = pScenario;
			if (pCourseId == 0)
			{
				// TODO: QUERY DOMAIN TO SEE IF USER CAN CREATE COURSE UNDER ACADEMICPLAN

				var vPlan = Application.DomainMaster.Planning.GetAcademicPlan(pPlanId);

				if (vPlan == null)
					throw new HttpException(404, Tr("Oops! We could not find the resource you requested."));

				vFormModel.AcademicPlan = vPlan;
			}
			else
			{
				var vCourse = Application.DomainMaster.Planning.GetCourse(pCourseId);
				if (vCourse == null)
					throw new HttpException(404, Tr("Oops! We could not find the resource you requested."));
				// TODO: QUERY DOMAIN TO SEE IF USER CAN UPDATE COURSE

				vFormModel.Course = vCourse;
				vFormModel.AcademicPlan = vCourse.Plan;
			}

			return PartialView("CourseForm", vFormModel);
		}

		/// <summary>
		/// Serves a <c>AcademicScheduleForm</c> control.
		/// </summary>
		/// <param name="pScenario">The scenario to use the <c>AcademicScheduleForm</c> under.</param>
		/// <param name="pAcademicScheduleId">The identifier of the <c>AcademicSchedule</c> to use in the form.</param>
		/// <param name="pPlanId">The identifier of the <c>AcademicPlan</c> to use in the form.</param>
		/// <returns>The <c>AcademicScheduleForm</c> control.</returns>
		/// <exception cref="T:System.Web.HttpException">
		/// Thrown with status code 404 if an academic schedule or the academic plan with the given 
		/// identifier does not exist in the system.
		/// </exception>
		/// <seealso cref="P:Application"/>
		/// <seealso cref="P:AcademicPlanner.Presentation.AcademicPlannerWebApp.DomainMaster"/>
		/// <seealso cref="P:AcademicPlanner.Domain.DomainMaster.Planning"/>
		/// <seealso cref="M:AcademicPlanner.Domain.Components.AcademicPlanningMngr.GetAcademicPlan(int)"/>
		/// <seealso cref="P:AcademicPlanner.Domain.DomainMaster.Scheduling"/>
		/// <seealso cref="M:AcademicPlanner.Domain.Components.AcademicSchedulingMngr.GetAcademicSchedule"/>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Get)]
		[AjaxOnly]
		[RequireAuthentication]
		public PartialViewResult AcademicScheduleForm(AcademicScheduleFormScenario pScenario, int pAcademicScheduleId,
														int pPlanId)
		{
			var vFormModel = new AcademicScheduleFormModel();

			vFormModel.Scenario = pScenario;
			if (pAcademicScheduleId == 0)
			{
				// TODO: QUERY DOMAIN TO SEE IF USER CAN CREATE ACADEMICSCHEDULE UNDER ACADEMICPLAN

				var vPlan = Application.DomainMaster.Planning.GetAcademicPlan(pPlanId);

				if (vPlan == null)
					throw new HttpException(404, Tr("Oops! We could not find the resource you requested."));

				vFormModel.AcademicPlan = vPlan;
			}
			else
			{
				var vSchedule = Application.DomainMaster.Scheduling.GetAcademicSchedule(pAcademicScheduleId);
				if (vSchedule == null)
					throw new HttpException(404, Tr("Oops! We could not find the resource you requested."));
				// TODO: QUERY DOMAIN TO SEE IF USER CAN UPDATE ACADEMICSCHEDULE

				vFormModel.Schedule = vSchedule;
				vFormModel.AcademicPlan = vSchedule.Plan;
			}

			return PartialView("AcademicScheduleForm", vFormModel);
		}

		/// <summary>
		/// Serves a <c>AcademicPlanControl</c> control.
		/// </summary>
		/// <param name="pAcademicPlanId">The identifier of the <c>AcademicPlan</c> to use in the control.</param>
		/// <param name="pHtmlId">The html id to give the control.</param>
		/// <returns>The <c>AcademicPlanControl</c> control.</returns>
		/// <exception cref="T:System.Web.HttpException">
		/// Thrown with status code 404 if an academic plan with the given identifier does not exist
		/// in the system.
		/// </exception>
		/// <seealso cref="P:Application"/>
		/// <seealso cref="P:AcademicPlanner.Presentation.AcademicPlannerWebApp.DomainMaster"/>
		/// <seealso cref="P:AcademicPlanner.Domain.DomainMaster.Planning"/>
		/// <seealso cref="M:AcademicPlanner.Domain.Components.AcademicPlanningMngr.GetAcademicPlan(int)"/>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Get)]
		[AjaxOnly]
		[RequireAuthentication]
		public PartialViewResult AcademicPlanControl(int pAcademicPlanId, string pHtmlId)
		{
			var vControlModel = new AcademicPlanControlModel();
			var vPlan = Application.DomainMaster.Planning.GetAcademicPlan(pAcademicPlanId);

			if (vPlan == null)
				throw new HttpException(404, Tr("Oops! We could not find the resource you requested."));

			vControlModel.AcademicPlan = vPlan;
			vControlModel.Id = pHtmlId;

			return PartialView("AcademicPlanControl", vControlModel);
		}

		/// <summary>
		/// Serves a <c>AcademicScheduleControl</c> control.
		/// </summary>
		/// <param name="pAcademicScheduleId">
		/// The identifier of the <c>AcademicSchedule</c> to use in the control.
		/// </param>
		/// <returns>The <c>AcademicScheduleControl</c> control.</returns>
		/// <exception cref="T:System.Web.HttpException">
		/// Thrown with status code 404 if an academic schedule with the given identifier does not exist
		/// in the system.
		/// </exception>
		/// <seealso cref="P:Application"/>
		/// <seealso cref="P:AcademicPlanner.Presentation.AcademicPlannerWebApp.DomainMaster"/>
		/// <seealso cref="P:AcademicPlanner.Domain.DomainMaster.Scheduling"/>
		/// <seealso cref="M:AcademicPlanner.Domain.Components.AcademicSchedulingMngr.GetAcademicSchedule"/>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Get)]
		[AjaxOnly]
		[RequireAuthentication]
		public PartialViewResult AcademicScheduleControl(int pAcademicScheduleId)
		{
			var vControlModel = new AcademicScheduleControlModel();
			var vSchedule = Application.DomainMaster.Scheduling.GetAcademicSchedule(pAcademicScheduleId);

			if (vSchedule == null)
				throw new HttpException(404, Tr("Oops! We could not find the resource you requested."));

			vControlModel.AcademicSchedule = vSchedule;

			return PartialView("AcademicScheduleControl", vControlModel);
		}
	}
}
